Repository navigation
Conversation
Since JuliaLang/julia#59765 (Julia 1.13) `Base.Precompilation.precompilepkgs` returns the cache files it found or produced, which code loading uses. `Pkg.precompile` passed that value through, so calling it at the REPL started printing a vector of `.ji` paths. That value is not part of `Pkg.precompile`'s API; return `nothing` as before. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Precompile cache file names are keyed on the project path, so two environments mounted at the same path (containers sharing a depot, both with their project at /work) get the same cache file names and overwrite each other's caches (JuliaLang/julia#63268). The manifest now carries an identity Julia can key the names on instead. `environment_id` is the project uuid when the project has one, otherwise a UUID generated the first time the manifest is written and kept from then on. `environment_name` mirrors the project name and is left out when there is none. Both are refreshed by `write_env` whenever an existing or changed manifest is written, so they follow later edits to the project file; a manifest is never created just for them. In a workspace they come from the root project, whose directory holds the manifest. A generated id is marked with a trailing `# generated` comment, since nothing else in the file says where it came from. Writing the entries bumps the manifest format to 2.2. Co-authored-by: Claude Code (Fable 5.1) <noreply@anthropic.com>
… Pkg.test (#4830) gen_target_project copied the tested package's [sources] into the sandbox project unchanged, and sandbox then resolved relative paths against the active project. Testing a workspace member from the workspace root therefore looked for its path sources relative to the root. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Detect URLs in `REPLMode` with the shared `isurl`
`src/REPLMode/argument_parsers.jl` carried its own URL detection in `looks_like_url`, and a second, stricter list in `looks_like_complete_url`. The two had drifted, so `extract_url_revision` left a `#rev` suffix inside the URL for any SSH user other than `git`:
pkg> add myorg@host:v3/org/proj/Repo.jl#main
Both now go through `isurl`, which that file already imports, and `looks_like_complete_url` defers to `looks_like_url`, so the two cannot diverge again.
The guard that was inlined in `looks_like_url` becomes `looks_like_version_spec`: an all-numeric host in `user@host:path` is a version, not an address, unless it has the three dots of an IPv4 address.
A string containing `.git` is no longer a URL on that basis alone. The regex replaced in 94d9551 required `.git` at the end of an otherwise complete URL, so the suffix narrowed the match; carried over as a standalone `contains` test it widened it instead, and matched `.gitignore` and `foo.github.io`. `isurl` treats the suffix as optional, which is what it was.
`looks_like_url` gains `file://`, which `isurl` recognises.
Fixes #4826
* Preserve explicit URL scheme detection
---------
Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com>
`is_local_repo` called `ispath` on the URL. That is a `stat` syscall against a PATH_MAX-bounded buffer, so a URL longer than PATH_MAX raised ENAMETOOLONG instead of returning `false`, aborting the enclosing clone or fetch before any network activity. PATH_MAX is 1024 on macOS and 4096 on Linux, so a remote may work on Linux and fail on macOS. `ispath_nothrow` is added alongside the `isdir_nothrow` and `isfile_nothrow` already in `src/utils.jl`, and like them answers `false` rather than propagating. `is_local_repo` now returns where it raised, and is otherwise unchanged. Fixes #4825
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Since #3848 an `add` auto-precompiles only the added packages and their dependencies. When the resolve also changes packages that were already in the manifest, such as downgrading a dependency to satisfy the new requirement, the packages that depend on them keep caches built against the old versions, and are only rebuilt the next time they are loaded. Now the changed packages and everything that depends on them are precompiled along with the added packages. The rest of the environment is still left alone, as #3848 intended. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
`contrib/list_missing_pkg_tags.jl` cloned the whole julia repository and checked out every release tag to find which releases bundle a Pkg commit that has no matching tag here. The new manually triggered workflow reads julia's tag list with `git ls-remote` and fetches `stdlib/Pkg.version` only for releases that lack a Pkg tag. It checks that each commit exists in this repository and writes the `git tag` and `git push` commands to the job summary. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
`extract_url_revision` asked `looks_like_complete_url`, which wanted a `.` or a `/` on top of being a URL, so a scp-like URL with a dotless host and a slashless path kept its suffix:
pkg> add git@server:repo#main
That test helped when `looks_like_url` was a list of prefixes. It now goes through `isurl`, which already requires a colon and a path, so `looks_like_complete_url` is removed and `extract_url_revision` calls `looks_like_url`.
…hallow registry test (#4843) * CI: run the Windows tests under the default git line-ending config The Windows job set `core.autocrlf false` globally so that the checkout kept the test fixtures' LF line endings. That also changed how LibGit2 checks out the repositories the tests create, so tests passed here that fail on machines with Git for Windows' default `core.autocrlf true`, such as julia's Buildkite Windows agents. Keep the fixtures byte-for-byte with a `.gitattributes` instead, and drop the global override. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * test: compare the shallow registry update result independent of line endings The checkout follows `core.autocrlf`, which Git for Windows turns on by default, so the file can have CRLF line endings there. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ves (#4844) The precompile workload registered TestPkg under the tree hash of its git commit, but served a tarball made from the files on disk. On Windows the two hashes differ, so the download failed its hash check with a warning and Pkg fell back to cloning the repository, leaving the pkg server download path uncovered there. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test: load test packages in a subprocess Test files share worker processes, so a package that one test file loads stays loaded for the later files on that worker, where it changes the answers of for example `Base.isprecompiled` and package resolution. Load test packages in a fresh julia process instead. The read-only checks of an installed package look up its source file without loading it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: check that no test file loads packages into the test process After each test file, fail if it left a package loaded other than a stdlib, a package of the test environment, or an extension of those, and name the packages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#4845) The server behind the download cancellation test only signalled a disconnect when the client closed cleanly. A client that closes with unread data in its receive buffer resets the connection instead, `eof` then throws `ECONNRESET`, and the signal was skipped. The cancelled curl transfer often ends that way on FreeBSD, where the test timed out in every recent Pkg bump on JuliaLang/julia CI. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Use Resolver.jl's SAT-based resolver by default Switch the default resolver to Resolver.jl (exact SAT-based resolution with an explicit preference order and a diagnosis on unsatisfiable resolves); the legacy maxsum resolver stays selectable with `JULIA_PKG_RESOLVER=maxsum`. Resolver.jl comes in through `[sources]`, pinned at its current `main`. `src/SATResolve.jl` adapts the output of `Operations.deps_graph` to Resolver.jl's `PkgData` universe and `Problem`: - Only the strong-dependency closure of the requirements is built. Packages reachable through weak edges alone can never be installed, and building conflict matrices for the whole weak closure was the dominant cost. - Requirement version specs and project `[compat]` entries are passed as `compat`, pins as `pin`, and the active/workspace projects are folded into those constraints instead of being modelled as packages, so a diagnosis can say "your compat leaves ...", "your pin leaves ...", "unpin X". - A `Diagnosis` is rebuilt over package names and rendered with Resolver's own report; fixes that would drop the synthetic julia requirement are filtered out. A requirement matching no available version is reported directly with the versions that exist. - The diagnosis only runs on the final tier of `tiered_resolve` (`diagnose_unsat`). Tests: a `resolver backends` testset in `test/api.jl`, backend-agnostic wording in two existing assertions, and `Utils.host_deps_depot` appended to the depot of subprocess tests that load the dev Pkg in an isolated depot. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Update Resolver.jl pin to current main Picks up the report wording from the review (restricts/constrains ... to, dependency instead of requirement, a note instead of "Blocked fixes") and the shadow-aware ranges, so the rendering nits are gone. `Conflict` gained a `shadows` field, passed through when the diagnosis is renamed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * CI: instantiate the docs workspace with the shipped Pkg The docs step loaded the checkout's Pkg with `--project` before any Manifest existed, which now fails since Resolver is not a stdlib. Use the shipped Pkg for the instantiate; it writes the workspace Manifest with Resolver, and the docs build then loads the checkout's Pkg as before. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Copy the artifacts of Pkg's deps into the loaded test depot The `concurrent` tests spawn Julia processes that load the dev Pkg from an isolated depot path (a temp depot plus the shared loaded depot). With the SAT resolver, Pkg depends on `Resolver` and thereby `libpicosat_jll`; `copy_this_pkg_cache` carried their source and compile caches into the loaded depot but not their artifacts, so the JLL failed in `__init__` with `Artifact "libpicosat" was not found` and all CI test jobs failed. Copy the host-platform artifacts of each dependency checkout along with its source, selected from the package's `Artifacts.toml`. Appending the host depot with `host_deps_depot()` instead would leak the host's packages into the test, which asserts that exactly one process installs FFMPEG. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Keep deps whose compat excludes a non-upgradable stdlib in the SAT resolver `SATResolve.build_pkg_data` dropped the dependency edge to a non-upgradable stdlib when the registry compat on it excluded the stdlib version shipped with this julia, so the stdlib never made it into the package's manifest deps. Relax the compat to `VersionSpec()` and keep the edge instead, as `Resolve.Graph` does since #4802. Fixes the `stdlib_compat` test for #4801 on this branch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Update Resolver.jl pin to current main Picks up sourced constraint kinds and the `sources` field on `Diagnosis`, which the adapter does not use yet, and the polynomial `lift_actions`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Add a changelog entry for the SAT-based resolver Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Give every isolated test depot the caches of Pkg's loaded dependencies `Base.compilecache` tells a precompile worker to keep the modules its parent has loaded, at the parent's build ids. The test process now has Preferences, JLLWrappers, libpicosat_jll and Resolver loaded through Pkg, so a test that precompiled anything depending on Preferences or JLLWrappers in a fresh depot (`BigProject` in test/repl.jl) failed with "Module Preferences with build ID … is missing from the cache" and then a strict-mode error, since the fresh depot held no cache for those build ids. The copies that `copy_this_pkg_cache` made into the loaded depot only covered `isolate(loaded_depot = true)`. Populate a `DEPS_DEPOT` once per test run with the loaded dependencies' compile caches, sources and artifacts, and append it to the depot path of every `isolate` and `temp_pkg_dir` depot. Subprocesses that get `DEPOT_PATH` now find Pkg's dependencies through it, which replaces `host_deps_depot()`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Skip Aqua's persistent-tasks check while Resolver is a registry dependency The check loads Pkg from a wrapper environment whose manifest Aqua synthesizes without the `[deps.X.syntax]` tables Pkg records. Resolver's cache, recorded with the syntax version of this julia since it declares no julia compat, is rejected there as "parsed for a different Julia syntax version", its dependencies are recompiled in the host depot and the cache of Pkg is orphaned, so the check ends in "Precompiling Pkg is disallowed". Skip it until Aqua carries the syntax entries over, or Resolver is bundled with Pkg and has no manifest entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Vendor Resolver.jl Pkg is a stdlib and cannot depend on a registered package, so carry an unmodified copy of Resolver.jl in vendor/Resolver. vendor/update_resolver.sh replaces it with a given upstream revision (or one from a local checkout) and records the commit in vendor/Resolver.version; with --check, run in CI, it verifies the copy matches that commit. The copy keeps upstream's style, so Runic, pre-commit and codecov skip vendor/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Load the vendored Resolver instead of the registry package Resolver becomes `Pkg.Resolver`, and Pkg depends on its dependencies, the libpicosat_jll and Serialization stdlibs. Pkg thereby has no non-stdlib dependencies again, so drop the workarounds that needed: the deps depot of the tests, the copied artifacts, the skipped Aqua persistent-tasks check and the docs instantiate with the shipped Pkg. The closure-box and unbound-args checks skip the vendored code, which is checked upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the legacy resolver out of Pkg's image The precompile workload resolves with the SAT resolver, but inference also followed the maxsum branch, which is chosen at runtime, and compiled it into Pkg's image. Call it through an inference barrier: it is opt-in, and its first use may take the compile latency. julia master, median of 9 `import Pkg`, Pkg master alongside: before after import Pkg (Pkg master) 907 ms 842 ms (522 / 537 ms) Pkg's package image 62.8 MB 57.7 MB cached specializations of or on Pkg code 22607 20568 of or on Pkg.Resolve code 2102 128 The first resolve with JULIA_PKG_RESOLVER=maxsum now compiles for ~1.4 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Run the SAT resolver on package names The resolver ran on UUIDs, and its diagnosis was rebuilt over display names for the report, so all of the report code, and the data it prints, was compiled for both. Key the resolver's input by the display names (unique per resolve) from the start and map the solution back to UUIDs; the priority order is still by name, then UUID, and the report reads as before. julia master, median of 9 `import Pkg`, Pkg master alongside: before after import Pkg (Pkg master) 842 ms 836 ms (537 / 548 ms) Pkg's package image 57.7 MB 56.1 MB cached specializations of or on Pkg code 20568 19678 of or on Resolver code 9896 8948 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Always give the SAT resolver a version order Without preferred versions the order was `nothing`, so the resolve call took `Union{Nothing, <closure>}`; inference widened that call to `Function` arguments and compiled the resolver for those as well. Give the order in every case: newest first is the universe's own layout, which the resolver detects in one pass. julia master, median of 9 `import Pkg`, Pkg master alongside: before after import Pkg (Pkg master) 836 ms 816 ms (548 / 537 ms) Pkg's package image 56.1 MB 55.6 MB cached specializations of or on Pkg code 19678 19529 of Resolver's own methods 1470 1328 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update vendored Resolver.jl to 159d919 Changes since dc5186b: 159d919 Do not resolve recursively in upstream probes 7e4dd9a Do not parameterize DepsProvider on its provider b59ce58 Make Problem concrete in its constraint and source maps 5654339 Give Constraint an inner constructor e8202c9 Remove closure boxes (kc/ttfx on top of JuliaLang/Resolver.jl#131, not upstream yet.) julia master, median of 9 `import Pkg`, Pkg master alongside: before after import Pkg (Pkg master) 816 ms 674 ms (537 / 558 ms) Pkg's package image 55.6 MB 50.2 MB cached specializations of or on Pkg code 19529 16782 of or on Resolver code 8806 6077 of Resolver's own methods 1328 821 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update vendored Resolver.jl to 3faf4bc Same content as 159d919, now that JuliaLang/Resolver.jl#131 and #132 are merged on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Check vendored Resolver for closure boxes and unbound args again Fixed upstream in JuliaLang/Resolver.jl#131, which is now vendored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* Share manifest parsing across constructor and input specializations * Share status rendering, registry updates, and Project parsing * Share GC usage-path collection without nested generators
* Name the workspace's project files when their compat entries collide In a workspace every member's compat entry on a package is intersected into one spec before anything is resolved, and when that intersection is empty the error said only that it was: "empty intersection between JSON@* and project compatibility ∅". Which member wrote which entry, and so which file to open, the reader had to work out by hand. The error now lists the entries it intersected, each with the project file it came from, relative to the workspace root. Outside a workspace nothing changes: there is one project file, and it is the one the reader is in. Co-Authored-By: Kristoffer Carlsson <kcarlsson89@gmail.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Name the workspace project file and line in resolver errors In a workspace the compat entries of every project file are intersected into one requirement spec, so a failed resolve could only say "your compat restricts X" and "drop dependency X", leaving the reader to find which member declares it -- and, in a workspace of any size, to grep for it. Each member's compat entry now goes to the SAT resolver as a constraint of its own, under a kind that names where it was declared, and each requirement records the files that list it as a dependency. The diagnosis then prints the place after the thing: "your compat (Sub1/Project.toml:5) restricts DataFrames to >=1.7.0", "relax your compat on PrettyTables (Sub2/Project.toml:5)", "drop dependency DataFrames (Sub1/Project.toml:2)". The place is a `path:line` so that an editor opens at the entry to change; TOML.parse drops line numbers, so the line is found by scanning the file for the entry, and a file whose entry cannot be found is named by its path alone. A file's entry is attributed only where the requirement spec honours it -- a stdlib's spec is let float regardless of what the members say -- and an entry that admits every version of the package is no constraint and is not named. Outside a workspace nothing changes. Co-Authored-By: Kristoffer Carlsson <kcarlsson89@gmail.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Use the platform's path separator in workspace resolver-error tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Changes since 3faf4bc (JuliaLang/Resolver.jl#133): - e021073 Avoid nested iterator machinery in diagnosis printing - 8843a8f Avoid nested generator inference in diagnostic cover collection - d0d2570 Share reachability and compaction kernels across optional inputs - c9ed325 Share `mark_necessary!` pruning kernel across setup specializations Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…4850) When a package is registered in several registries, two code paths applied a registry's `Deps.toml`/`Compat.toml` ranges to versions that registry does not have (#4849). The resolver already guards against this through `query_compat_for_version_multi_registry!`, but: - `Registry.query_deps_for_version` unioned deps from every registry whose range covered the version when building the manifest, so a dependency only declared by a registry lacking the resolved version could end up in the manifest entry. - `Operations.status_compat_info` queried every registry for a dependent's compat, so `Pkg.status(outdated = true)` could report that dependent as holding a package back based on a registry that does not contain the dependent's version. `query_deps_for_version` now takes the per-registry version sets that `deps_graph` already computes and skips registries without the version, and `status_compat_info` only consults registries whose `version_info` has the dependent's version. Fixes #4849 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…4818) * Remove [sources] entry for PTR * [temp] --verbose * Tweak wording * Set memory per worker to 1GiB
* why: print a dependency tree instead of enumerating paths The old output listed every path from a direct dependency to the package, which multiplies through diamonds in the graph (1369 lines for Preferences in a 264-package environment). Print an inverted tree instead: the package at the root, its dependents below, direct dependencies highlighted, and subtrees already shown marked with (*). The new --forward option prints the same paths top-down, starting at the direct dependencies. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * changelog entry for why tree output Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test: load registry before capturing why output The fresh CI depot printed the registry install messages into the captured IOBuffer, matching the pattern used by the other testsets. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * why: put arrows on the tree branches to show the dependency direction The bottom-up tree uses ├─← (the child depends on the parent) and the forward tree ├─→, matching the A → B notation the old output used. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* Reduce more package-image code duplication - Don't specialize on `julia_version` (`VersionNumber` or `nothing`) in the resolve path: `resolve_versions!`, `deps_graph`, `collect_fixed!`, `update_manifest!`, `collect_project` and `SATResolve`. - `atomic_toml_write`: print the TOML to a buffer and write it with a closure-free `atomic_write`, so the temp-dir code is compiled once instead of per data type, keyword set and file mode. - `Registry.update`: convert the cooldown to `Millisecond` and pick the registries inside the lock closure, so the closure has one type. - `download_source`: copy the fields it needs into a `DownloadPkg` and run the download code once for `PackageSpec` and `PackageEntry`. - `@nospecialize` the `Union` arguments of `validate_manifest`, `status_compat_info`, `collect_project`, `GitTools.clone` and `fetch`. Pkg package image on Julia 1.14 nightly: native code 6338 -> 5972 KiB (-5.8%), .so 18941 -> 18015 KiB, .text 6472 -> 6103 KiB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Build REPL command tables without specializing on their entries `PSA[...]` literals specialized `getindex` on the types of every declaration's entries, and `CommandSpec(; dec...)`/`OptionSpec(; x...)` compiled a keyword call per combination of keys and value types. Build the vectors with a `@nospecialize`d `getindex` and read declarations from a `Dict`, rejecting unknown keys as the keyword constructors did. Pkg package image on Julia 1.14 nightly: 585 fewer code instances, .ji -850 KiB, compressed inferred IR -166 KiB, native code -45 KiB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Honor [compat] entries for [extras] packages in resolution A compat entry for a package listed under [extras] was only consulted by `resolve`, which errored on it, while `update` and `instantiate` ignored it. Add such entries as weak requirements of the loaded projects, so the package is constrained when it is in the environment (e.g. as an indirect dependency) without being added to it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * changelog: link PR number Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * shorten comment Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Include extras compat in the resolve hash Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Expect the `NewOnly` project to be unsatisfiable at instantiate The `NewOnly` test project has a `[compat]` entry for its `[extras]` package `ScientificTypes` that no version allowed by its direct dependency satisfies. Now that extras compat is honored by `Pkg.instantiate`, the project is already unsatisfiable before `Pkg.test` is reached, so the test asserts that instead of expecting `instantiate` to succeed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Drop the changelog and docs entries for extras compat Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* Fix resolving a `subdir` package that is not installed yet When `handle_repo_add!` looks a package up by its known tree hash (e.g. from the manifest), the object it finds is already the tree of the package inside `subdir`. Indexing `subdir` into it again failed with "Did not find subdirectory", so `Pkg.resolve` and `Pkg.pin` errored for subdir packages whose manifest entry was not installed in the depot. Skip the `subdir` step when a tree-hash lookup found a tree; rev lookups are unchanged. Fixes #4851 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Simplify the tree-hash check and name the repository in lookup errors A lookup by `pkg.tree_hash` can only return the object with that hash, which is the package tree, so the `gitobject isa LibGit2.GitTree` guard never changes the outcome. Check `pkg.tree_hash === nothing` directly and explain why in a comment. The "Did not find rev" and "Did not find subdirectory" errors now name the repository (and the rev for the subdirectory case), and the "Did not find tree" error says that the manifest's tree is no longer reachable and that updating the package resolves it again from its rev. The unreachable-tree test checks that `Pkg.update` does exactly that. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Don't suggest updating a package whose recorded commit is unreachable When the manifest's tree is no longer reachable and the package was added at a commit, that commit is gone too, so updating fails with "Did not find rev". Tell the user to add the package again at a rev that still exists instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com>
Resolving with `PRESERVE_ALL_INSTALLED` (offline mode, or
`JULIA_PKG_PRESERVE_TIERED_INSTALLED`) filtered the versions of every
package in the dependency graph with `is_package_downloaded`, which probed
the depots for each version separately and re-parsed `HostPlatform()` on
every call. The graph was also expanded through the dependencies of every
version, including the ones just filtered out, so the registry data of the
whole historical dependency closure had to be parsed.
`deps_graph` now reads the installed slugs of a package once and only calls
`is_package_downloaded` for versions that are present, computes the platform
once per resolve, and only follows the dependencies of versions that passed
the filtering (the resolvers never look at the dependencies of the others).
An offline `Pkg.add("JSON")` in an empty environment on a depot with ~1500
installed packages went from ~1.1 s to ~0.14 s; `is_package_downloaded`
calls went from 42k to 1.9k and the number of packages whose registry info
is parsed from 1446 to 18. The resolved manifest is unchanged, as is the
online tier, where every non-yanked version is valid.
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Reading a compressed registry meant decompressing the tarball and walking ~75k tar entries into a Dict on every session that touched the registry (~90 ms plus GC). Instead, build a per-registry cache file once (registries/.cache/<Name>-<treehash>.v1.bin) with a per-package index and the uncompressed TOML files, and mmap it so a session only pays for the packages it uses. Loading the registry drops from ~90 ms to ~2 ms; first Pkg.status()/Pkg.add go from ~125 ms to ~19 ms. JULIA_PKG_REGISTRY_CACHE=false restores the old path. On Windows a mapped file can neither be removed nor replaced, which would break registry removal and updates, so the cache is read into memory there instead. The tests share one cache between depots instead of building one per depot. Also avoid work on the first operation of a session: Registry.update no longer asks the pkg server for registry urls when every registry is on cooldown (an HTTPS round trip of ~100-200 ms), Resolve.logstr no longer specializes on the type of stderr, the TOML printer used for usage logs is precompiled explicitly, and gc's usage reduction uses a loop instead of a broadcast. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
An entry replaces every compatibility constraint on a package, including those of the packages that depend on it and the project's own [compat], with the given one, e.g. to try a new version of a package that a dependency has not been updated to allow yet. It is keyed by a name in [deps] or [weakdeps]; a weakdep is not added to the environment, so that is how an indirect dependency is overridden. Only the overrides of the loaded projects apply. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…4861) * sandbox: ignore path `[sources]` leading out of an installed package Packages in monorepos (OrdinaryDiffEq.jl, Lux.jl and others) ship `[sources]` entries such as `Core = {path = "../Core"}` that point at sibling packages in the repository. When such a package is installed by tree hash, only its own subdirectory is on disk, so `Pkg.test` and `Pkg.build` failed before running anything with "expected package ... to exist at path". This made those packages impossible to test outside a repository checkout, including under PkgEval. When the package being tested or built is installed rather than developed, drop the path sources of its sandbox project that lead out of the package directory, so those dependencies resolve from the registry. Sources inside the package, such as a `test/Project.toml` pointing at `..`, are kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * CHANGELOG: note ignored path `[sources]` of installed packages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * sandbox: Also ignore manifest paths leading out of an installed package Some monorepo subpackages track their siblings through a committed test/Manifest.toml (`path = "../../Sibling"`) instead of `[sources]`, as BinaryReedSolomon does. Installed, those paths lead out of the package too, and `Pkg.test` failed the same way. Leave such manifest entries out of the sandbox, so those dependencies also resolve from the registry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The SAT resolver builds its answer layer by layer, maximizing the packages of a
layer one at a time in the `by` priority order and pinning each. That order was
the package name, so a low-level package that sorts early could be maximized
before a package depending on it and hold it back many releases. For example,
`Pkg.add("TuringGLM")` maximized `Distributions` to 0.25.131 before `Turing`, and
since the newest `Turing` (0.40.5) does not support that `Distributions`, it got
`Turing` 0.24.4, `DynamicPPL` 0.21.6 and `SciMLBase` 1.92 (39 packages older than
the maxsum resolver picks) for four patch releases of `Distributions`. PkgEval on
1.14 hit this for `TuringGLM`, `SensitivityRankCondition` and `ThreeBodyTB`, where
the old releases are broken on 1.14.
Order a layer by the size of each package's transitive dependency closure
(over the dependencies of all its versions), largest first, then by name and
UUID, so a package goes before the packages it can pull in. `closure_sizes`
takes a few milliseconds on the ~1000-package graphs of those adds.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#4863) #4858 replaced the keyword constructors `CommandSpec(; ...)` and `OptionSpec(; ...)` with methods taking a declaration vector, so that Pkg does not compile a keyword call per declaration shape. Packages that extend the Pkg REPL with their own commands (CondaPkg, PreferenceTools) construct `CommandSpec` with keywords, and now fail to precompile with a `MethodError`, taking everything depending on CondaPkg/PythonCall down with them. Add keyword methods that forward to the declaration-vector constructors. Pkg itself does not call them, so its package image is unaffected. Assisted-by: Claude Code (Opus 5.5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.1)
Can you help keep this open source service alive? 💖 Please sponsor : )